/*
 * This file is part of jboss-admin-rest
 * Copyright 2009, Christos Vasilakis (cvasilak@gmail.com)
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.admin.rest.services;

import org.jboss.admin.rest.domain.LogBean;
import org.jboss.admin.rest.exceptions.BadRequestException;
import org.jboss.admin.rest.exceptions.InternalServerErrorException;
import org.jboss.resteasy.annotations.providers.jaxb.Formatted;
import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Produces( {"application/xml", "application/json"} )  
public class LogResource {

	enum LogType {

		ALL("ALL"),
		DEBUG("DEBUG"),
		ERROR("ERROR"),
		FATAL("FATAL"),
		INFO("INFO"),
		WARN("WARN");
		private final String type;

		private LogType(String type) {
			this.type = type;
		}

		public String getType() {
			return type;
		}
	}

	@GET
	@Wrapped(element = "logs")
	@Formatted
	public List<LogBean> listLogs(@Context UriInfo uriInfo) {

		List<LogBean> logs = new ArrayList<LogBean>();

		File logDir = new File(System.getProperty("jboss.server.log.dir"));
		File[] logFiles = logDir.listFiles();

		UriBuilder builder = uriInfo.getBaseUriBuilder().path(LogResource.class, "getLog");

		for (File logFile : logFiles) {
			if (!logFile.isDirectory()) {
				logs.add(new LogBean(builder.build(logFile.getName())));
			}
		}

		return logs;
	}

	@GET
	@Path("/{name}")
	@Produces("text/plain")
	public String getLog(@PathParam("name") String name, @QueryParam("type") @DefaultValue("all") String type) throws BadRequestException, InternalServerErrorException {
		/* TODO:
		 *   a more 'sophisticated' log handling is needed
		 *   e.g. filter by date / class name etc
		 *
		 */
		String logDir = System.getProperty("jboss.server.log.dir");

		File file = new File(logDir + "/" + name + ".log");

		if (!file.exists()) {
			file = new File(logDir + "/" + name);

			if (!file.exists()) {
				throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity("log file not found!").build());
			}
		}

		StringBuilder output = new StringBuilder();

		BufferedReader reader = null;
		LogType logType = null;

		try {
			logType = LogType.valueOf(type.toUpperCase());

			reader = new BufferedReader(new FileReader(file));

			String line;

			while ((line = reader.readLine()) != null) {
				if (logType != LogType.ALL) {
					String[] splits = line.split(" ");

					if (splits.length >= 3 &&
							(splits[1].equals(logType.getType()) /* covers the 'boot.log' case */ || splits[2].equals(logType.getType()))) {
						output.append(line).append("\n");
					}
				} else {
					output.append(line).append("\n");
				}
			}

		} catch (IllegalArgumentException e) {
			throw new BadRequestException("unknown log type specified, only 'all', 'debug', 'error', 'fatal', 'info', 'warn' are accepted!");
		} catch (IOException e) {
			throw new InternalServerErrorException("I/O exception occured: " + e.getMessage(), e);
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				throw new InternalServerErrorException("I/O exception closing log file!", e);
			}
		}

		return output.length() > 0 ? output.toString() : "entries with log type '" + logType.getType() + "' not found!";
	}
}
